package org.adl.registry.website.mail;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletRequest;

/**
 * Provides methods for sending mail.
 * @author Jacob Marks - Joint ADL Co-Lab
 * @version 1.0
 * @license This software is licensed as open source software pursuant to the terms defined in the Joint ADL Co-Lab Open Source Software License.  Use of any part of this software constitutes acceptance of this license. The Joint ADL Co-Lab open source agreement is available at {@link http://adlregistry.adlnet.gov/source_license.html}.
 */
public class MailUtil
{
    /**
     * Sends an email.
     * 
     * @param iFrom The <CODE>String</CODE> address from which the message should appear to have been sent.
     * @param iRecipient The <CODE>String</CODE> address to which the message should be been sent.
     * @param iSubject The <CODE>String</CODE> subject of the message.
     * @param iMessage The <CODE>String</CODE> body of the message.
     * @throws javax.mail.internet.AddressException Throws <CODE>AddressException</CODE> if the provided from or recipient email address are invalid.
     * @throws javax.mail.MessagingException Throws <CODE>MessagingException</CODE> if an error is encountered while relaying the message.
     */
    public static void sendEmail(String iFrom, String iRecipient, String iSubject, String iMessage)
    throws AddressException, MessagingException
    {
        InternetAddress from = new InternetAddress(iFrom);
        
        InternetAddress[] recipients = new InternetAddress[1];
        
        recipients[1] = new InternetAddress(iRecipient);
        
        MailUtil.sendEmail(from, recipients, iSubject, iMessage);
    }
    
    /**
     * Sends an email.
     * 
     * @param iFrom The <CODE>String</CODE> address from which the message should appear to have been sent.
     * @param iRecipients The <CODE>String</CODE> array of addresses to which the message should be been sent.
     * @param iSubject The <CODE>String</CODE> subject of the message.
     * @param iMessage The <CODE>String</CODE> body of the message.
     * @throws javax.mail.internet.AddressException Throws <CODE>AddressException</CODE> if the provided from or recipient email address are invalid.
     * @throws javax.mail.MessagingException Throws <CODE>MessagingException</CODE> if an error is encountered while relaying the message.
     */
    public static void sendEmail(String iFrom, String[] iRecipients, String iSubject, String iMessage)
    throws AddressException, MessagingException
    {
        InternetAddress from = new InternetAddress(iFrom);
        
        InternetAddress[] recipients = new InternetAddress[iRecipients.length];
        
        for (int i = 0; i < iRecipients.length; i++)
        {
            recipients[i] = new InternetAddress(iRecipients[i]);
        }
        
        MailUtil.sendEmail(from, recipients, iSubject, iMessage);
    }
    
    /**
     * Sends an email.
     * 
     * @param iFrom The <CODE>String</CODE> address from which the message should appear to have been sent.
     * @param iRecipient The <CODE>InternetAddress</CODE> address to which the message should be been sent.
     * @param iSubject The <CODE>String</CODE> subject of the message.
     * @param iMessage The <CODE>String</CODE> body of the message.
     * @throws javax.mail.MessagingException Throws <CODE>MessagingException</CODE> if an error is encountered while relaying the message.
     */
    public static void sendEmail(InternetAddress iFrom, InternetAddress iRecipient, String iSubject, String iMessage)
    throws MessagingException
    {
        InternetAddress[] recipients = new InternetAddress[] { iRecipient };
        
        MailUtil.sendEmail(iFrom, recipients, iSubject, iMessage);
    }
    
    /**
     * Sends an email.
     * 
     * @param iFrom The <CODE>InternetAddress</CODE> from which the message should appear to have been sent.
     * @param iRecipients The <CODE>InternetAddress</CODE> array of addresses to which the message should be been sent.
     * @param iSubject The <CODE>String</CODE> subject of the message.
     * @param iMessage The <CODE>String</CODE> body of the message.
     * @throws javax.mail.MessagingException Throws <CODE>MessagingException</CODE> if an error is encountered while relaying the message.
     */
    public static void sendEmail(InternetAddress iFrom, InternetAddress[] iRecipients, String iSubject, String iMessage)
    throws MessagingException
    {
        Properties p = new Properties();
        
        p.put("mail.smtp.host", MailUtil.getMailHost());
        
        Session     session = Session.getInstance(p);
        MimeMessage msg     = new MimeMessage(session);
        
        msg.setFrom(iFrom);
        msg.setRecipients(Message.RecipientType.TO, iRecipients);
        msg.setSubject(iSubject);
        msg.setSentDate(new Date());
        msg.setText(iMessage);
        Transport.send(msg);
    }
    
    /**
     * Gets the mail host frm the website property file.
     * 
     * @return Returns the mail server host name which is to handle message relaying for the website.
     */
    public static String getMailHost()
    {
        String host = "localhost";
        
        try
        {
            host = MailUtil.getProperty("mail_host");
        }
        catch (IOException ex)
        {
            //Do nothing. Mail host will be assumed to be the localhost.
        }
        
        return host;
    }
    
    /**
     * Gets the helpdesk address from the website property file.
     * 
     * @return Returns the helpdesk email address stored in the website properties file.
     */
    public static String getSupportEmailAddress()
    {
        String host = "";
        
        try
        {
            host = MailUtil.getProperty("support_address");
        }
        catch (IOException ex)
        {
            //Do nothing. Helpdesk email address will be assumed to be an empty string.
        }
        
        return host;
    }
    
    /**
     * Gets the host information from a ServeltRequest initiating a form based email submission.
     * @param iRequest The <CODE>ServletRequest</CODE> of the Servlet handling the submission of a form based email.
     * @return Returns a formatted <CODE>String</CODE> for inclusion in an email message containing the IP address and Host information of the computer initiating the submission of a form based email.
     */
    public static String getHostInfoFromRequestAsString(ServletRequest iRequest)
    {
        StringBuilder output = new StringBuilder();
        
        String ip = iRequest.getRemoteAddr();
        String host = iRequest.getRemoteHost();
        
        output.append("IP Address: " + ip);
        output.append("\r");
        output.append("Host Info: " + host);
        
        return output.toString();
    }
    
    /**
     * Gets a property from the mail library configuration file.
     * @param iPropertyName The <CODE>String</CODE> name of the property to be retrieved from the mail library configuration file.
     * @return Returns the <CODE>String</CODE> value of the specified property.
     * @throws java.io.FileNotFoundException Throws <CODE>FileNotFoundException</CODE> if the mail configuration file cannot be found.
     * @throws java.io.IOException Throws <CODE>IOException</CODE> if the mail configuration file cannot be read.
     */
    private static String getProperty(String iPropertyName)
    throws FileNotFoundException, IOException
    {
        String value = "";
        
        String configFilePath = System.getenv("REGISTRY_WEBSITE_HOME");
        
        Properties properties = new Properties();
        
        String path = configFilePath + "mail.properties";
        
        FileInputStream fis = new FileInputStream(path);
        
        properties.load(fis);
        
        value = properties.getProperty(iPropertyName);
        
        fis.close();
        
        return value;
    }
}
